﻿#region Copyright 
/*-------------------------------------------------------------------------
* 命名空间名称/文件名:    SSPivot.Common.Extensions/RandomExtensions 
* CLR版本:     4.0.30319.42000
* 机器名称:    DESKTOP-NHMLO8A
* 功 能：       N/A
* 类 名：       RandomExtensions
* 创建时间：  2025/6/4 11:30:01
* 版本号：      v1.0
* 创建人:        xulong
*-------------------------------------------------------------------------*/
#endregion
using JetBrains.Annotations;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;

namespace System
{
    public static class RandomExtensions
    {
        /// <summary>
        /// 生成真正的随机数
        /// </summary>
        /// <param name="r"></param>
        /// <param name="seed"></param>
        /// <returns></returns>
        public static int StrictNext(this Random r, int seed = int.MaxValue)
        {
            return new Random((int)Stopwatch.GetTimestamp()).Next(seed);
        }
        /// <summary>
        /// 产生正态分布的随机数
        /// </summary>
        /// <param name="rand"></param>
        /// <param name="mean">均值</param>
        /// <param name="stdDev">方差</param>
        /// <returns></returns>
        public static double NextGauss(this Random rand, double mean, double stdDev)
        {
            double u1 = 1.0 - rand.NextDouble();
            double u2 = 1.0 - rand.NextDouble();
            double randStdNormal = Math.Sqrt(-2.0 * Math.Log(u1)) * Math.Sin(2.0 * Math.PI * u2);
            return mean + stdDev * randStdNormal;
        }

        /// <summary>
        ///  从指定值返回随机值的随机扩展方法。
        /// </summary>
        /// <typeparam name="T">Generic type parameter.</typeparam>
        /// <param name="this">The @this to act on.</param>
        /// <param name="values">A variable-length parameters list containing arguments.</param>
        /// <returns>One of the specified value.</returns>
        public static T OneOf<T>([NotNull] this Random @this, params T[] values)
        {
            return values[@this.Next(values.Length)];
        }

        /// <summary>
        ///  抛硬币的随机扩展方法。
        /// </summary>
        /// <param name="this">The @this to act on.</param>
        /// <returns>true 50% of time, otherwise false.</returns>
        public static bool CoinToss([NotNull] this Random @this)
        {
            return @this.Next(2) == 0;
        }

        /// <summary>
        /// 获取随机字符
        /// </summary>
        /// <param name="intSize"></param>
        /// <returns></returns>
        static public string GetRandomCode([NotNull] this Random @this, int intSize)
        {
            string strRtn = "";

            char[] ocdChars = "123456789ABCDEFGHJKMNPQRSTUVWXYZ".ToCharArray();
            for (int i = 0; i < intSize; i++)
            {
                strRtn += ocdChars[@this.Next(0, ocdChars.Length)].ToString();
            }

            return strRtn;
        }
        /// <summary>
        /// 获取随机数字
        /// </summary>
        /// <param name="intSize"></param>
        /// <returns></returns>
        static public string GetRandomNumber([NotNull] this Random @this, int intSize)
        {
            string strRtn = "";
            char[] ocdChars = "0123456789".ToCharArray();
            for (int i = 0; i < intSize; i++)
            {
                strRtn += ocdChars[new Random(GetRandomSeed()).Next(i > 0 ? 0 : 1, ocdChars.Length)].ToString();
            }
            return strRtn;
        }

        /// <summary>
        /// 获取随机字母
        /// </summary>
        /// <param name="intSize"></param>
        /// <returns></returns>
        static public string GetRandomLetter(int intSize)
        {
            string strRtn = "";
            char[] ocdChars = "abcdefghjkmnpqrstuvwxyz".ToCharArray();
            for (int i = 0; i < intSize; i++)
            {
                strRtn += ocdChars[new Random(GetRandomSeed()).Next(0, ocdChars.Length)].ToString();
            }
            return strRtn;
        }
        public static int GetRandomSeed()
        {
            byte[] bytes = new byte[4];
            var rng = RandomNumberGenerator.Create();
            rng.GetBytes(bytes);
            return BitConverter.ToInt32(bytes, 0);
        }
        /// <summary>
        /// 生成随机验证码
        /// </summary>
        /// <param name="length">验证码长度</param>
        /// <param name="isNumberOnly">验证码是否是纯数字</param>
        /// <returns></returns>
        public static string GenerateRandomCode(int length, bool isNumberOnly = false)
        {
            char[] array;
            if (isNumberOnly)
            {
                array = ConstantNumber;
            }
            else
            {
                array = Constant;
            }
            var stringBuilder = new StringBuilder(length);
            for (var i = 0; i < length; i++)
            {
                //stringBuilder.Append(array[Random.Next(array.Length)]);
                stringBuilder.Append(array[new Random().StrictNext(array.Length)]);
            }
            return stringBuilder.ToString();
        }
        private static readonly char[] ConstantNumber = new[]
       {
            '0',
            '1',
            '2',
            '3',
            '4',
            '5',
            '6',
            '7',
            '8',
            '9'
        };
        private static readonly char[] Constant = new[]
        {
            '0',
            '1',
            '2',
            '3',
            '4',
            '5',
            '6',
            '7',
            '8',
            '9',
            'a',
            'b',
            'c',
            'd',
            'e',
            'f',
            'g',
            'h',
            'i',
            'j',
            'k',
            'l',
            'm',
            'n',
            'o',
            'p',
            'q',
            'r',
            's',
            't',
            'u',
            'v',
            'w',
            'x',
            'y',
            'z'
        };
    }
}
